﻿<template>
  <baseUI :isShow="myConfig.isShow" label="" :showLabel="false" :commonConfig="commonConfig">
    <div class="clearfix" style="float: left; padding: 3px 0 5px 0"  v-if="myConfig.isEnable">
        <el-button type="success" @click="addRow" :disabled="editRowIndex >= 0" round>添加 <i class="el-icon-plus"></i></el-button>
        <el-button type="primary" @click="clickSave" :disabled="editRowIndex >= 0" v-if="myConfig.other.activeSave" round>保存 <i class="el-icon-edit"></i></el-button>
    </div>
    <div :style="myConfig.myStyle" v-if="myConfig.other.columns">
      <el-table v-if="isDesignMode"
        :data="data"
        style="width: 100%;"
        max-height="400"
        border
        stripe
        @row-click="handleRowClick"
        @row-dblclick="handleRowDbclick">
          <el-table-column v-for="(col, index) in columns" :key="index"
            :prop="col.column.name"
            :label="col.column.title"
            :width="col.column.width?col.column.width:'auto'"
            align="center">
            <template slot-scope="scope">
              <template v-if="myConfig.isEnable && editRowIndex === scope.$index">
                <component :key="col.component.config.uid"
                  :ref="col.component.config.uid"
                  v-bind:is="col.component.componentName"
                  :config="col.component.config"
                  :commonConfig="commonConfig"
                  :value.sync="scope.row[col.column.name]"
                  :isDesignMode="true"
                  @onDesignEvent="handleEmbeddedDesignEvent"></component>
              </template>
              <template v-else>
                <template v-if="!col.viewer.isComponent">
                  <span v-if="Object.keys(scope.row).indexOf(col.column.name + '__text') < 0">{{scope.row[col.column.name]}}</span>
                  <span v-else>{{scope.row[col.column.name + '__text']}}</span>
                </template>
                <template v-else>
                  <component :key="col.viewer.component.config.uid"
                  :ref="col.viewer.component.config.uid"
                  v-bind:is="col.viewer.component.componentName"
                  :config="col.viewer.component.config"
                  :commonConfig="commonConfig"
                  :value.sync="scope.row[col.column.name]"
                  :isDesignMode="true"
                  @onDesignEvent="handleEmbeddedDesignEvent"></component>
                </template>
              </template>
            </template>
          </el-table-column>
          <el-table-column width='auto' align="center" label="操作" v-if="myConfig.isEnable">
            <template slot-scope="scope">
              <el-button type = "success" circle size = "mini" @click = "handleRowEdit(scope.$index)" title = '编辑' v-if="editRowIndex !== scope.$index">
                <i class = "iconfont icon-iconset0137"></i>
              </el-button>
              <el-button type = "success" circle size = "mini" @click = "handleRowEditCancel(scope.$index)" title = '完成' v-else>
                <i class = "el-icon-check"></i>
              </el-button>
              <el-button type = "info" circle size = "mini" @click = "handleRowRemove(scope.$index)" title = '移除'>
                <i class = "iconfont icon-shanchu"></i>
              </el-button>
            </template>
          </el-table-column>
      </el-table>
      <el-table v-else
        :data="data"
        style="width: 98%;"
        max-height="400"
        border
        stripe
        @row-click="handleRowClick"
        @row-dblclick="handleRowDbclick">
          <el-table-column v-for="(col, index) in columns" :key="index"
            :prop="col.column.name"
            :label="col.column.title"
            :width="col.column.width?col.column.width:'auto'"
            align="center">
            <template slot-scope="scope">
              <template v-if="myConfig.isEnable && editRowIndex === scope.$index">
                <component :key="col.component.config.uid"
                  :ref="col.component.config.uid"
                  v-bind:is="col.component.componentName"
                  :config="col.component.config"
                  :events="col.component.events"
                  :commonConfig="commonConfig"
                  :value.sync="scope.row[col.column.name]"
                  :isDesignMode="false"
                  :pageModel.sync="dataModel[scope.$index]"
                  :pageControl.sync="dataControl[scope.$index]"
                  :parentControl.sync="pageControl"
                  :parentModel="getDataObjFromPageModel()"
                  @onRuntimeEvent="onRuntimeEvent"></component>
              </template>
              <template v-else>
                <template v-if="!col.viewer.isComponent">
                  <span v-if="Object.keys(scope.row).indexOf(col.column.name + '__text') < 0">{{scope.row[col.column.name]}}</span>
                  <span v-else>{{scope.row[col.column.name + '__text']}}</span>
                </template>
                <template v-else>
                  <component :key="col.viewer.component.config.uid"
                  :ref="col.viewer.component.config.uid"
                  v-bind:is="col.viewer.component.componentName"
                  :config="col.viewer.component.config"
                  :events="col.viewer.component.events"
                  :commonConfig="commonConfig"
                  :value.sync="scope.row[col.column.name]"
                  :isDesignMode="false"
                  :pageModel.sync="dataModel[scope.$index]"
                  :pageControl.sync="dataControl[scope.$index]"
                  :parentControl.sync="pageControl"
                  :parentModel="getDataObjFromPageModel()"
                  @onRuntimeEvent="onRuntimeEvent"></component>
                </template>
              </template>
            </template>
          </el-table-column>
          <el-table-column width='auto' align="center" label="操作" v-if="myConfig.isEnable">
            <template slot-scope="scope">
              <el-button type = "success" circle size = "mini" @click = "handleRowEdit(scope.$index)" title = '编辑' v-if="editRowIndex !== scope.$index">
                <i class = "iconfont icon-iconset0137"></i>
              </el-button>
              <el-button type = "success" circle size = "mini" @click = "handleRowEditCancel(scope.$index)" title = '完成' v-else>
                <i class = "el-icon-check"></i>
              </el-button>
              <el-button type = "info" circle size = "mini" @click = "handleRowRemove(scope.$index)" title = '移除'>
                <i class = "iconfont icon-shanchu"></i>
              </el-button>
            </template>
          </el-table-column>
      </el-table>
    </div>
    <div style="padding: 10px 0 0 0" v-if="myConfig.other.showPageNavigation">
      <el-pagination
        background
        :disabled="editRowIndex >= 0"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page.sync = "page"
        :page-size = 'pageSize'
        :pager-count = "5"
        :page-sizes = "[10, 25, 50, 100]"
        layout = "total, sizes, prev, pager, next"
        :total = 'rowTotal'>
      </el-pagination>
    </div>
  </baseUI>
</template>
<script>
import baseComponent from '../baseComponent.vue'
import baseUI from '../baseUI.vue'
import {commonUse_defaultMethod} from '@/components/commonUse'
import {getComponentByName, getTableColumnViewerByName} from '../common'
export default {
  components: {
    baseUI
  },
  extends: baseComponent,
  mounted () {
    this.load()
  },
  data () {
    return {
      dataModel: [],
      dataControl: [],
      viewerModel: [],
      viewerControl: [],
      data: [],
      deletedData: [],
      page: 1,
      pageSize: 10,
      rowTotal: 0,
      isChanged: false,
      isLoad: false,
      editRowIndex: -1
    }
  },
  methods: {
    isDataComponent () {
      return true
    },
    handleSizeChange (val) {
      let self = this
      if (this.isChanged && this.myConfig.other.activeSave) {
        this.isChanged = false
        self.$confirm('数据还未保存，确认是否保存?', '提示', {
          confirmButtonText: '确定',
          cancelButtonClass: 'el-button--info',
          cancelButtonText: '取消'
        }).then(() => {
          self.save().then(data => {
            self.pageSize = val
            self.load()
          })
        }).catch(() => {
          self.pageSize = val
          self.load()
        })
      } else {
        self.pageSize = val
        self.load()
      }
    },
    handleCurrentChange (val) {
      let self = this
      if (this.isChanged && this.myConfig.other.activeSave) {
        this.isChanged = false
        self.$confirm('数据还未保存，确认是否保存?', '提示', {
          confirmButtonText: '确定',
          cancelButtonClass: 'el-button--info',
          cancelButtonText: '取消'
        }).then(() => {
          self.save().then(data => {
            self.page = val
            self.load()
          })
        }).catch(() => {
          self.page = val
          self.load()
        })
      } else {
        self.page = val
        self.load()
      }
    },
    load (data) {
      if (data) {
        this.setValue(data)
        this.isLoad = true
      } else {
        // 根据设定进行数据查询和加载
        if (this.myConfig.other.dataSource && this.myConfig.other.dataSource.remoteCategory) {
          if (this.myConfig.other.dataSource.remoteCategory === 'Meta') {
            this.loadFromMeta(this.myConfig.other.dataSource.MetaSettings)
          } else if (this.myConfig.other.dataSource.remoteCategory === 'API') {
            this.loadFromAPI(this.myConfig.other.dataSource.APISettings)
          }
        }
      }
    },
    save () {
      let self = this
      return new Promise((resolve, reject) => {
        if ((!self.data || self.data.length <= 0) && (!self.deletedData || self.deletedData.length <= 0)) {
          self.$message.error('待保存的数据不可为空')
          return
        }
        if (!self.myConfig.other.dataSave) {
          self.$message.error('保存未做设定')
        } else {
          if (self.myConfig.other.dataSave.remoteCategory === 'Meta') {
            if (self.myConfig.other.dataSave.MetaSettings.table) {
              let fixed_data = {}
              self.myConfig.other.dataSave.MetaSettings.fixedData.forEach(el => {
                fixed_data[el.column] = commonUse_defaultMethod(el.value, self.getDataObjFromPageModel(), self.getFixedDataObject(), null, self.parentModel)
              })
              self.$api.mdFormSave({
                id: self.myConfig.other.dataSave.MetaSettings.table,
                data: self.getDataObjectFromDataModel(),
                deletedData: self.deletedData,
                fixed_data_express: fixed_data
              }).then(data => {
                resolve(data)
                self.isChanged = false
                self.load()
              })
            } else {
              self.$message.error('保存未做设定:请选择元数据表')
            }
          } else if (self.myConfig.other.dataSave.remoteCategory === 'API') {
            if (self.myConfig.other.dataSave.APISettings.api_uid) {
              let parameters = {}
              self.myConfig.other.dataSave.APISettings.input_header.forEach(el => {
                parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
              })
              self.myConfig.other.dataSave.APISettings.input_path.forEach(el => {
                parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
              })
              self.myConfig.other.dataSave.APISettings.input_querystring.forEach(el => {
                parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
              })
              self.myConfig.other.dataSave.APISettings.input_postdata.forEach(el => {
                parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
              })
              this.$api.excuteDFormEvent(self.myConfig.other.dataSave.APISettings.api_uid, {}, parameters).then(data => {
                resolve(data)
                self.isChanged = false
                self.load()
              })
            } else {
              self.$message.error('保存未做设定:请选择事件')
            }
          }
        }
      })
    },
    loadFromMeta (settings) {
      if (!settings) return
      if (!settings.table) return
      let self = this
      let filterExpress = {}
      let orderExpress = {}
      let otherFilterExpress = {}
      if (settings.filterList) {
        settings.filterList.forEach((item, index) => {
          if (Object.keys(filterExpress).indexOf(item.column) < 0) {
            filterExpress[item.column] = {}
          }
          let v = commonUse_defaultMethod(item.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
          filterExpress[item.column][item.condition] = v
        })
      }
      if (settings.fixedFilter) {
        settings.fixedFilter.forEach((item, index) => {
          if (Object.keys(otherFilterExpress).indexOf(item.column) < 0) {
            otherFilterExpress[item.column] = {}
          }
          let v = commonUse_defaultMethod(item.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
          otherFilterExpress[item.column][item.condition] = v
        })
      }
      if (settings.orderList) {
        settings.orderList.forEach((item, index) => {
          if (Object.keys(orderExpress).indexOf(item.column) < 0) {
            orderExpress[item.column] = 'asc'
          }
          orderExpress[item.column] = item.direction
        })
      }
      this.$api.mdFormQuery({
        id: settings.table,
        limit: settings.showPageNavigation ? this.pageSize : 1000,
        page: settings.showPageNavigation ? this.page : 1,
        fixed_filter_express: filterExpress,
        fixed_orderby_express: orderExpress,
        other_condition_express: otherFilterExpress
      }).then(data => {
        self.isLoad = true
        self.deletedData = []
        self.page = data.page
        self.pageSize = data.limit
        self.rowTotal = data.total_count
        self.data = data.data
        self.dataModel = []
        self.dataControl = []
        self.viewerModel = []
        self.viewerControl = []
        self.data.forEach((item, index) => {
          self.dataModel.push({})
          self.dataControl.push({
            showInnerPop: false,
            innerPageUid: '',
            innerRowData: {},
            showOutPop: false,
            outPopUrl: '',
            refreshPage: false,
            reset: false
          })
          self.viewerModel.push({})
          self.viewerControl.push({
            showInnerPop: false,
            innerPageUid: '',
            innerRowData: {},
            showOutPop: false,
            outPopUrl: '',
            refreshPage: false,
            reset: false
          })
        })
      })
    },
    loadFromAPI (settings) {
      let parameters = {}
      let self = this
      settings.input_header.forEach(el => {
        parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
      })
      settings.input_path.forEach(el => {
        parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
      })
      settings.input_querystring.forEach(el => {
        parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
      })
      settings.input_postdata.forEach(el => {
        parameters[el.key] = commonUse_defaultMethod(el.value, this.getDataObjFromPageModel(), this.getFixedDataObject(), null, this.parentModel)
      })
      this.$api.excuteDFormEvent(settings.api_uid, {}, parameters).then(data => {
        if (self.myConfig.other.showPageNavigation) {
          let page = self.getValueFromDataObjectByKey(settings.pageObject, data)
          let pageSize = self.getValueFromDataObjectByKey(settings.pageSizeObject, data)
          let rowtotal = self.getValueFromDataObjectByKey(settings.totalRowObject, data)
          if (!page || (typeof page !== 'number')) {
            this.$message.error('从API获取翻页信息失败，可能原因:page对象未正确设置或该API未正确返回翻页信息')
            return
          }
          if (!pageSize || (typeof pageSize !== 'number')) {
            this.$message.error('从API获取翻页信息失败，可能原因:pageSize对象未正确设置或该API未正确返回翻页信息')
            return
          }
          if (!rowtotal || (typeof rowtotal !== 'number')) {
            this.$message.error('从API获取翻页信息失败，可能原因:rowTotal对象未正确设置或该API未正确返回翻页信息')
            return
          }

          self.page = page
          self.pageSize = pageSize
          self.rowTotal = rowtotal
        }
        let list = self.getValueFromDataObjectByKey(settings.dataObject, data)
        if (!list) {
          this.$message.error('从API获取资料失败，可能原因:返回数据模型未正确设置')
          return
        }
        if (!Array.isArray(list)) {
          this.$message.error('从API获取的数据集类型不正确，可能原因:返回数据模型未正确设置或该API未正确返回数据集')
          return
        }
        self.data = list
        self.dataModel = []
        self.viewerModel = []
        self.deletedData = []
        self.dataControl = []
        self.viewerControl = []
        self.data.forEach((item, index) => {
          self.dataModel.push({})
          self.dataControl.push({
            showInnerPop: false,
            innerPageUid: '',
            innerRowData: {},
            showOutPop: false,
            outPopUrl: '',
            refreshPage: false,
            reset: false
          })
          self.viewerModel.push({})
          self.viewerControl.push({
            showInnerPop: false,
            innerPageUid: '',
            innerRowData: {},
            showOutPop: false,
            outPopUrl: '',
            refreshPage: false,
            reset: false
          })
        })
      })
    },
    setValue (val) {
      if (val && Array.isArray(val)) {
        this.data = val
        let self = this
        self.dataModel = []
        self.dataControl = []
        self.viewerModel = []
        self.viewerControl = []
        self.isLoad = true
        self.deletedData = []
        this.data.forEach((item, index) => {
          self.dataModel.push({})
          self.dataControl.push({
            showInnerPop: false,
            innerPageUid: '',
            innerRowData: {},
            showOutPop: false,
            outPopUrl: '',
            refreshPage: false,
            reset: false
          })
          self.viewerModel.push({})
          self.viewerControl.push({
            showInnerPop: false,
            innerPageUid: '',
            innerRowData: {},
            showOutPop: false,
            outPopUrl: '',
            refreshPage: false,
            reset: false
          })
        })
      }
    },
    getValue () {
      return this.getDataObjectFromDataModel()
    },
    getComponetByColumn (column) {
      let rtn = getComponentByName(column.ui_type)
      rtn.config.dataKey = column.name
      rtn.config.label = column.title
      rtn.config.showLabel = false
      return rtn
    },
    onRuntimeEvent (event, data) {
    },
    handleRowRemove (index) {
      let arr = this.data.splice(index, 1)
      this.dataModel.splice(index, 1)
      this.dataControl.splice(index, 1)
      this.viewerModel.splice(index, 1)
      this.viewerControl.splice(index, 1)
      this.editRowIndex = -1
      if (this.myConfig.other.dataSource.remoteCategory === 'Meta') {
        arr.forEach(d => {
          if (d['_default_pk']) {
            this.deletedData.push(d)
          }
        })
      }
    },
    addRow () {
      let row = {}
      this.myConfig.other.columns.forEach((item, index) => {
        row[item.name] = ''
        switch (item.component.componentName) {
          case 'SelectInput':
            row[item.name + '__text'] = ''
            break
          case 'RadioInput':
            row[item.name + '__text'] = ''
            break
          case 'CheckBoxInput':
            row[item.name + '__text'] = ''
            break
          case 'CadecaseSelectInput':
            row[item.name + '__text'] = ''
            break
          case 'PopInput':
            row[item.name + '__text'] = ''
            break
        }
      })
      this.dataModel.splice(0, 0, {})
      this.dataControl.splice(0, 0, {
        showInnerPop: false,
        innerPageUid: '',
        innerRowData: {},
        showOutPop: false,
        outPopUrl: '',
        refreshPage: false,
        reset: false
      })
      this.viewerModel.splice(0, 0, {})
      this.viewerControl.splice(0, 0, {
        showInnerPop: false,
        innerPageUid: '',
        innerRowData: {},
        showOutPop: false,
        outPopUrl: '',
        refreshPage: false,
        reset: false
      })
      this.data.splice(0, 0, row)
      this.$nextTick(() => {
        this.editRowIndex = 0
      })
    },
    handleEmbeddedDesignEvent (event, sender, targetData) {
      this.$emit('onDesignEvent', event, sender, targetData)
    },
    handleRowClick (row, column, event) {
      let index = -1
      this.onRowClick(row, index)
    },
    handleRowDbclick (row, column, event) {
      let index = -1
      this.onRowDClick(row, index)
    },
    getFixedDataObject () {
      return {
        limit: this.pageSize,
        page: this.page
      }
    },
    getValueFromDataObjectByKey (key, data) {
      if (!key) return data
      let arr = key.split('.')
      let obj = data
      arr.forEach(key => {
        if (obj && obj[key]) {
          obj = obj[key]
        } else {
          obj = null
        }
      })
      return obj
    },
    clickSave () {
      let self = this
      this.save().then(data => {
        self.load()
      })
    },
    handleRowEdit (index) {
      this.editRowIndex = index
    },
    handleRowEditCancel (index) {
      this.editRowIndex = -1
    },
    setTextContent4Data () {
      if (this.isDesignMode) return
      if (!this.data || this.data.length <= 0 || this.editRowIndex < 0) return
      let self = this
      // 重置__text的值
      self.myConfig.other.columns.forEach(col => {
        if (Object.keys(self.data[self.editRowIndex]).indexOf(col.name + '__text') >= 0) {
          self.data[self.editRowIndex][col.name + '__text'] = self.dataModel[self.editRowIndex][col.name].component.getText()
        }
      })
    },
    getDataObjectFromDataModel () {
      let rtn = []
      let self = this
      this.data.forEach((item, index) => {
        let cols = self.columns
        let d = {}
        for (let i = 0; i < cols.length; i++) {
          d[cols[i].column.name] = item[cols[i].column.name]
        }
        if (self.myConfig.other.dataSource.remoteCategory === 'Meta') {
          d['_default_pk'] = self.data[index]._default_pk ? self.data[index]._default_pk : ''
        }
        rtn.push(d)
      })
      return rtn
    }
  },
  computed: {
    columns: function () {
      let rtn = []
      this.myConfig.other.columns.forEach((item, index) => {
        if (item.active) {
          rtn.push({
            column: JSON.parse(JSON.stringify(item)),
            component: JSON.parse(JSON.stringify(item.component)),
            viewer: getTableColumnViewerByName(item.ui_type)
          })
        }
      })
      return rtn
    }
  },
  watch: {
    data: {
      handler: function (val, oldVal) {
        this.selectedValue = this.getValue()
        if (!this.isLoad) {
          this.isChanged = true
          this.setTextContent4Data()
        } else {
          this.isLoad = false
        }
      },
      deep: true
    },
    // 'myConfig.other.dataSource.MetaSettings.table': {
    //   handler: function (val, oldVal) {
    //     let self = this
    //     if (this.isDesignMode && this.myConfig.other.dataSource.remoteCategory === 'Meta') {
    //       this.$nextTick(() => {
    //         self.load()
    //       })
    //     }
    //   },
    //   deep: true
    // },
    'myConfig.other.dataSource.APISettings.api_uid': {
      handler: function (val, oldVal) {
        let self = this
        if (this.isDesignMode && this.myConfig.other.dataSource.remoteCategory === 'API') {
          this.$nextTick(() => {
            self.load()
          })
        }
      },
      deep: true
    },
    'myConfig.isEnable': {
      handler: function (val, oldVal) {
        console.debug('myConfig.isEnable=' + val)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
